#include <iostream>

/**
 * @brief 接口隔离的设计模式
 */
class RTType {
public:
    // 内部接口类
    class Impl {
    public:
        virtual ~Impl() = default;
        virtual void draw() const = 0;
        // virtual void calcTest() const =0;
        virtual void calcTest() const = 0;
    };

    // 构造函数接受一个实现类的指针
    RTType(Impl* impl) : pImpl(impl) {}

    // 提供一个公共接口
    void draw() const {
        pImpl->draw();
    }
    // 提供一个公共接口
    void calcTest() const {
        pImpl->calcTest();
    }

//- 实现运算符重载==
//- 实现运算符重载!=


private:
    Impl* pImpl;
};

// 实现一个具体的形状，如矩形
class Rectangle : public virtual RTType::Impl {
public:
    void draw() const override {
        std::cout << "Drawing a rectangle" << std::endl;
    }

    //测试这种设计模式下，定义子类特有的成员函数
    // NOTE: 这种在接口类没有的成员函数，不可以
    // 通过: RTType rect(new Rectangle())
    // 的 rect.calcTest()来访问子类的特有成员函数
    void printClassName(){
        std::cout << "Class name: " << typeid(*this).name() << std::endl;
    }

    void calcTest() const override
    {
        std::cout << "I am about to do something " << std::endl;
    }
};

// 实现另一个具体的形状，如圆形
class Circle : public virtual RTType::Impl {
public:
    void draw() const override {
        std::cout << "Drawing a circle" << std::endl;
    }

    void calcTest() const override
    {
        std::cout << "I am about to do something " << std::endl;
    }
};

int main() {
    // 创建一个矩形对象
    RTType rect(new Rectangle());
    //rect.printClassName();
    rect.draw(); // 输出 "Drawing a rectangle"

    // 创建一个圆形对象
    RTType circle(new Circle());
    circle.calcTest();
    circle.draw(); // 输出 "Drawing a circle"

    return 0;
}
